home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / ply15dat.zip / BALLS.C < prev    next >
C/C++ Source or Header  |  1992-09-19  |  6KB  |  182 lines

  1. /*
  2.  * balls.c - Create a set of shiny spheres, with each sphere blooming sets of
  3.  *     9 more spheres with 1/3rd radius.  None of the spheres are clipped.  A
  4.  *     square floor polygon is added.  Three light sources.
  5.  *
  6.  * Version:  2.2 (11/17/87)
  7.  * Author:  Eric Haines, 3D/Eye, Inc.
  8.  *
  9.  * SIZE_FACTOR determines the number of objects output.
  10.  *     Total spheres = sum of n=0,SF of (9**SF).
  11.  *
  12.  *     SIZE_FACTOR    # spheres    # squares
  13.  *        1            10             1
  14.  *        2            91             1
  15.  *        3           820             1
  16.  *
  17.  *        4          7381             1
  18.  */
  19.  
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <math.h>
  23. #include "def.h"
  24. #include "lib.h"
  25.  
  26. #define    OUTPUT_FORMAT        OUTPUT_CURVES
  27. #define    SIZE_FACTOR        3
  28.  
  29. static COORD4 objset[9];
  30.  
  31. /*
  32.  * Output the parent sphere, then output the children of the sphere.
  33.  * Uses global 'objset'.
  34.  */
  35. void
  36. output_objset(long depth, COORD4 *center, COORD4 *direction)
  37. {
  38.     double  angle;
  39.     COORD4  axis, z_axis;
  40.     COORD4  child_pt, child_dir;
  41.     MATRIX  mx;
  42.     long    num_vert;
  43.     double  scale;
  44.  
  45.     /* output sphere at location & radius defined by center */
  46.     lib_output_sphere(center, OUTPUT_CURVES);
  47.  
  48.     /* check if children should be generated */
  49.     if ( depth > 0 ) {
  50.     --depth ;
  51.  
  52.     /* rotation matrix to new axis from +Z axis */
  53.     if ( direction->z >= 1.0 ) {
  54.         /* identity matrix */
  55.         lib_create_identity_matrix( mx ) ;
  56.     }
  57.     else if ( direction->z <= -1.0 ) {
  58.         lib_create_rotate_matrix( mx, Y_AXIS, PI ) ;
  59.     }
  60.     else {
  61.         SET_COORD( z_axis, 0.0, 0.0, 1.0 ) ;
  62.         CROSS( axis, z_axis, (*direction) ) ;
  63.         lib_normalize_coord3( &axis ) ;
  64.         angle = acos( (double)DOT_PRODUCT( z_axis, (*direction) ) ) ;
  65.         lib_create_axis_rotate_matrix( mx, &axis, angle ) ;
  66.     }
  67.  
  68.     /* scale down location of new spheres */
  69.     scale = center->w * (1.0 + direction->w ) ;
  70.  
  71.     for ( num_vert = 0 ; num_vert < 9 ; ++num_vert ) {
  72.         lib_transform_coord( &child_pt, &objset[num_vert], mx ) ;
  73.         child_pt.x = child_pt.x * scale + center->x ;
  74.         child_pt.y = child_pt.y * scale + center->y ;
  75.         child_pt.z = child_pt.z * scale + center->z ;
  76.         /* scale down radius */
  77.         child_pt.w = center->w * direction->w ;
  78.         SUB3_COORD( child_dir, child_pt, (*center) ) ;
  79.         child_dir.x /= scale ;
  80.         child_dir.y /= scale ;
  81.         child_dir.z /= scale ;
  82.         child_dir.w = direction->w ;
  83.         output_objset(depth, &child_pt, &child_dir);
  84.     }
  85.     }
  86. }
  87.  
  88. /* Create the set of 9 vectors needed to generate the sphere set. */
  89. /* Uses global 'objset' */
  90. void
  91. create_objset()
  92. {
  93.     COORD4  axis, temp_pt, trio_dir[3] ;
  94.     double  dist ;
  95.     MATRIX  mx ;
  96.     long    num_set, num_vert ;
  97.  
  98.  
  99.     dist = 1.0 / sqrt( (double)2.0 ) ;
  100.  
  101.     SET_COORD4( trio_dir[0], dist, dist,   0.0, 0.0 ) ;
  102.     SET_COORD4( trio_dir[1], dist,  0.0, -dist, 0.0 ) ;
  103.     SET_COORD4( trio_dir[2],  0.0, dist, -dist, 0.0 ) ;
  104.  
  105.     SET_COORD( axis, 1.0, -1.0, 0.0 ) ;
  106.     lib_normalize_coord3( &axis ) ;
  107.     lib_create_axis_rotate_matrix(
  108.       mx,
  109.       &axis,
  110.       asin( (double) ( 2.0 / sqrt( (double)6.0 ) ) ) ) ;
  111.  
  112.     for ( num_vert = 0 ; num_vert < 3 ; ++num_vert ) {
  113.     lib_transform_coord( &temp_pt, &trio_dir[num_vert], mx ) ;
  114.     COPY_COORD( trio_dir[num_vert], temp_pt ) ;
  115.     }
  116.  
  117.     for ( num_set = 0 ; num_set < 3 ; ++num_set ) {
  118.     lib_create_rotate_matrix( mx, Z_AXIS, num_set*2.0*PI/3.0 ) ;
  119.     for ( num_vert = 0 ; num_vert < 3 ; ++num_vert ) {
  120.         lib_transform_coord( &objset[num_set*3+num_vert],
  121.                             &trio_dir[num_vert], mx ) ;
  122.     }
  123.     }
  124. }
  125.  
  126. void
  127. main(int argc, char *argv[])
  128. {
  129.     COORD4  back_color, obj_color ;
  130.     COORD4  backg[4], bvec, light ;
  131.     COORD4  from, at, up, dir;
  132.     COORD4  center_pt, direction ;
  133.     double  radius ;
  134.  
  135.    /* We are using Polyray */
  136.    lib_set_raytracer(OUTPUT_POLYRAY);
  137.  
  138.     /* set radius of sphere which would enclose entire object */
  139.     radius = 1.0 ;
  140.  
  141.     /* output viewpoint */
  142.     SET_COORD( from, 2.1, 1.3, 1.7 ) ;
  143.     SET_COORD( at, 0.0, 0.0, 0.0 ) ;
  144.     SET_COORD( up, 0.0, 0.0, 1.0 ) ;
  145.     lib_output_viewpoint( &from, &at, &up, 45.0, 1.0, 1.0, 256, 256);
  146.  
  147.     /* output background color - UNC sky blue */
  148.     SET_COORD( back_color, 0.078, 0.361, 0.753 ) ;
  149.     lib_output_background_color( &back_color ) ;
  150.  
  151.     /* output light sources */
  152.     SET_COORD4( light, 4.0, 3.0, 2.0, 0.6 ) ;
  153.     lib_output_light( &light ) ;
  154.     SET_COORD4( light, 1.0, -4.0, 4.0, 0.6 ) ;
  155.     lib_output_light( &light ) ;
  156.     SET_COORD4( light, -3.0, 1.0, 5.0, 0.6 ) ;
  157.     lib_output_light( &light ) ;
  158.  
  159.     /* output floor polygon - beige */
  160.     SET_COORD( back_color, 1.0, 0.75, 0.33 ) ;
  161.     lib_output_color(&back_color, 0.2, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0);
  162.     bvec.x = bvec.y = radius * 12.0 ;
  163.     bvec.z = -radius / 2.0 ;
  164.     SET_COORD( backg[0],  bvec.x,  bvec.y, bvec.z ) ;
  165.     SET_COORD( backg[1], -bvec.x,  bvec.y, bvec.z ) ;
  166.     SET_COORD( backg[2], -bvec.x, -bvec.y, bvec.z ) ;
  167.     SET_COORD( backg[3],  bvec.x, -bvec.y, bvec.z ) ;
  168.     lib_output_polygon( 4, backg);
  169.  
  170.     /* set up object color - off white */
  171.     SET_COORD( obj_color, 1.0, 0.9, 0.7 ) ;
  172.     lib_output_color(&obj_color, 0.1, 0.6, 0.7, 10.0, 0.0, 0.0, 0.0);
  173.  
  174.     /* create set of spawned points */
  175.     create_objset() ;
  176.  
  177.     /* compute and output object */
  178.     SET_COORD4( center_pt, 0.0, 0.0, 0.0, radius / 2.0 ) ;
  179.     SET_COORD4( direction, 0.0, 0.0, 1.0, 1.0/3.0 ) ;
  180.     output_objset(SIZE_FACTOR, ¢er_pt, &direction ) ;
  181. }
  182.